﻿using System;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using TextFileMerger.Models;
using TextFileMerger.Utilities;
//using static System.Windows.Forms.VisualStyles.VisualStyleElement;


namespace TextFileMerger
{
    // 使用partial关键字实现代码分离（与Designer.cs配合）
    public partial class MainForm : Form
    {
        private readonly SynchronizationContext _syncContext; // 保存UI线程上下文
        //解决报错：System.InvalidOperationException:“线程间操作无效: 从不是创建控件“lblStatus”的线程访问它。”
        //在Windows Forms中，控件（如标签、按钮等）的创建和修改必须在创建它们的线程上进行，通常是主UI线程。FileSystemWatcher的事件处理程序可能在后台线程触发，这意味着在事件处理程序中直接修改UI控件会导致跨线程访问的问题，从而引发异常。
        //要解决这个问题，必须确保对控件的访问发生在创建它们的线程上，即主UI线程。
        private DateTime _lastUpdate = DateTime.MinValue;  // 最后更新时间戳（用于节流控制）
        private const int UPDATE_INTERVAL = 500; // 节流时间500ms

        public MainForm() 
        {
            InitializeComponent();
            btnMerge.Enabled = false;
            this.Text = "智能文件合并工具 v1.0";
            this.StartPosition = FormStartPosition.CenterScreen;

            // 获取同步上下文
            _syncContext = SynchronizationContext.Current ?? throw new InvalidOperationException();

            // 初始化文件监控
            var watcher = new FileSystemWatcher
            {
                Path = FileHelper.EnsureDataDirectory(),
                Filter = "*.txt",
                NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
                EnableRaisingEvents = true
            };

            // 注册事件处理器
            watcher.Created += OnFileCreated;
            watcher.Error += OnWatcherError;
            watcher.Renamed += OnFileRenamed;

            // 窗体关闭时释放资源
            this.FormClosed += (_, __) => watcher.Dispose();
        }

        #region 文件监控事件处理
        private void OnFileCreated(object sender, FileSystemEventArgs e)
        {
            // 节流控制：500ms内只更新一次
            if ((DateTime.Now - _lastUpdate).TotalMilliseconds < UPDATE_INTERVAL) return;

            // 通过同步上下文更新UI（确保线程安全）
            _syncContext.Post(_ =>
            {
                _lastUpdate = DateTime.Now;
                UpdateStatusLabel($"检测到新文件: {e.Name}", Color.DarkGreen);
                System.Media.SystemSounds.Asterisk.Play();
                ResetLabelColorAfterDelay(2000);
            }, null);
        }

        // 文件重命名事件处理
        private void OnFileRenamed(object sender, RenamedEventArgs e)
        {
            _syncContext.Post(_ =>
            {
                UpdateStatusLabel($"文件重命名: {e.OldName} → {e.Name}", Color.DarkBlue);
            }, null);
        }

        // 监控错误事件处理
        private void OnWatcherError(object sender, ErrorEventArgs e)
        {
            var ex = e.GetException();
            _syncContext.Post(_ =>
            {
                UpdateStatusLabel($"监控错误: {ex.Message}", Color.DarkRed);
                System.Media.SystemSounds.Hand.Play();
                LogErrorToFile(ex);
            }, null);
        }
        #endregion

        #region UI辅助方法
        // 更新状态标签内容和颜色
        private void UpdateStatusLabel(string message, Color color)
        {
            lblStatus.Text = message;
            lblStatus.ForeColor = color;
        }

        // 延迟恢复状态标签颜色
        private void ResetLabelColorAfterDelay(int milliseconds)
        {
            Task.Delay(milliseconds).ContinueWith(t =>
            {
                _syncContext.Post(__ =>
                {
                    lblStatus.ForeColor = SystemColors.ControlText;
                }, null);
            });
        }

        // 记录错误日志到文件
        private void LogErrorToFile(Exception ex)
        {
            try
            {
                string logPath = Path.Combine(
                    FileHelper.EnsureDataDirectory(),
                    "error_log.txt");

                File.AppendAllText(logPath,
                    $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {ex}\n\n");
            }
            catch (Exception logEx)
            {
                _syncContext.Post(__ =>
                {
                    MessageBox.Show($"日志写入失败: {logEx.Message}",
                        "严重错误",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }, null);
            }
        }
        #endregion

        // 文件选择按钮1点击事件
        private void btnFile1_Click(object sender, EventArgs e)
        {
            SelectFile(txtFile1);
        }

        // 文件选择按钮2点击事件
        private void btnFile2_Click(object sender, EventArgs e)
        {
            SelectFile(txtFile2);
        }

        // 通用文件选择方法
        private void SelectFile(TextBox targetBox)
        {
            using (var dlg = new OpenFileDialog())
            {
                dlg.Filter = "文本文件|*.txt|所有文件|*.*";
                dlg.DefaultExt = "txt";  // 增加默认扩展名
                dlg.CheckFileExists = true;  // 验证文件存在
                dlg.Multiselect = false;  // 禁止多选

                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    targetBox.Text = dlg.FileName;
                    btnMerge.Enabled = File.Exists(txtFile1.Text) &&   // 验证两个文件路径的有效性
                                     File.Exists(txtFile2.Text);
                }
            }
        }

        // 合并按钮点击事件处理
        private void btnMerge_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(txtFile1.Text) || string.IsNullOrWhiteSpace(txtFile2.Text))     //没有选完文件则进行异常处理
                    throw new ArgumentException("请先选择两个文件");

                if (Path.GetExtension(txtFile1.Text).ToLower() != ".txt" ||        //程序只接受txt文件，如果文件后缀不是.txt则进行异常处理
                    Path.GetExtension(txtFile2.Text).ToLower() != ".txt")
                {
                    throw new ArgumentException("只支持合并文本文件(.txt)");
                }

                this.Cursor = Cursors.WaitCursor;   // 显示等待状态
                lblStatus.Text = "正在合并...";

                var merger = new FileMerger();     //创建合并对象
                string mergedContent = merger.MergeFiles(       //进行合并
                    txtFile1.Text,
                    txtFile2.Text,
                    radioAppend.Checked);

                string savePath = Path.Combine(       //保存文件路径
                    FileHelper.EnsureDataDirectory(),
                    FileHelper.GenerateFileName());

                File.WriteAllText(savePath, mergedContent);

                lblStatus.Text = $"合并成功！文件已保存到：{savePath}";
                System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{savePath}\"");
            }
            catch (Exception ex)             //处理异常
            {
                lblStatus.Text = "错误：" + ex.Message;
                MessageBox.Show(ex.Message, "操作失败",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 创建标准化按钮
        private Button CreateButton(string text, Color backColor)
        {
            return new Button
            {
                Text = text,
                BackColor = backColor,
                FlatStyle = FlatStyle.Flat,
                Margin = new Padding(3),
                Font = new Font("微软雅黑", 9.75F)
            };
        }

        // 创建标准化文本框
        private TextBox CreateTextBox()
        {
            return new TextBox
            {
                Margin = new Padding(3),
                ReadOnly = true,
                BackColor = Color.WhiteSmoke
            };
        }
        private void radioAppend_CheckedChanged(object sender, EventArgs e)
        {

        }
    }
}